home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / zmdm.zoo / transfer.c < prev    next >
C/C++ Source or Header  |  1991-04-27  |  17KB  |  986 lines

  1. /*
  2.  *     (Quick & Dirty) Transfer Shell
  3.  *
  4.  *    Jwahar Bammi
  5.  *     bang:   {any internet host}!dsrgsun.ces.CWRU.edu!bammi
  6.  *     domain: bammi@dsrgsun.ces.CWRU.edu
  7.  *    GEnie:    J.Bammi
  8.  */
  9.  
  10. #include "config.h"
  11.  
  12. #ifdef DLIBS
  13. #include <string.h>
  14. #endif
  15. #ifdef __GNUC__
  16. #include <string.h>
  17. #endif
  18.  
  19. #include "zmdm.h"
  20. #include "common.h"
  21.  
  22. #define ISWILD(X)    ((X == '*')||(X == '?'))
  23. #define PROMPT        fprintf(STDERR,"zmdm> ")
  24.  
  25. extern int dorz(), dosz(), ls(), rm(), cp(), cd(), md(), rd(), pwd(), df(),
  26.        hhelp();
  27.  
  28. #ifdef RECURSE
  29. extern int doszf();
  30. #endif
  31.  
  32. static struct comnds {
  33.     char    *command;    /* command string    */
  34.     int     (*routine)();    /* routine to invoke    */
  35.     char    *synopsis;    /* synopsis        */
  36.     int    expand;        /* expand wildcards before calling routine? */
  37. } comtab [] = {
  38.     { "rz",    dorz, "receive files using Z/X modem protocol",       TRUE },
  39.     { "rb", dorz, "receive files using Y modem protocol",         TRUE },
  40. #ifdef RECURSE
  41.     { "sz", doszf, "send files using Z/Y/X modem protocol",        TRUE },
  42. #else
  43.     { "sz", dosz, "send files using Z/Y/X modem protocol",        TRUE },
  44. #endif
  45.     { "sb", dosz, "send files using Y modem protocol",            TRUE },
  46.     { "rm", rm,   "remove files",                                 TRUE },
  47.     { "cp", cp,   "copy files",                                   TRUE },
  48.     { "ls", ls,   "list directory",                               FALSE},
  49.     { "cd", cd,   "change working directory",              FALSE},
  50.     { "md", md,   "make a directory",                  FALSE},
  51.     { "rd", rd,   "remove a directory",                  FALSE},
  52.     { "pwd",pwd,  "print  working directory",              FALSE},
  53.     { "df", df,   "check free space",                  FALSE},
  54.     { "?",  hhelp, "this message",                      FALSE},
  55.     { (char *)NULL, (int (*)())NULL, (char *)NULL,                FALSE}
  56. };
  57.  
  58. #define MAXARGS    1024
  59. static char *targv[MAXARGS];
  60. static int targc;
  61. char *alltolower();
  62.  
  63. void transfer()
  64. {
  65.     char linebuf[132];
  66.     char *line;
  67.     int command;
  68.     int status;
  69.     extern int find_command();
  70.     extern int expnd_args();
  71. #ifdef DEBUG
  72.     int i;
  73. #endif
  74.  
  75.     fprintf(STDERR,"hit <RETURN> to return to emulator,  <?> for help\n\n");
  76.     targc = 0;
  77.     while (TRUE)
  78.     {
  79.         if(targc > 1)
  80.             free_args();
  81.  
  82.         PROMPT;
  83.         linebuf[0] = 127;
  84. #ifndef REMOTE
  85.         Cconrs(linebuf);
  86. #else
  87.         Cconraux(linebuf);
  88. #endif
  89.         putc('\n', STDERR);
  90.         if(linebuf[1] == 0)
  91.         /* cancelled */
  92.         return;
  93.         
  94.         linebuf[(linebuf[1]+2)] = '\0';
  95.         line = &linebuf[2];
  96. #ifdef DEBUG
  97. printf("Line: |%s|\n", line);
  98. #endif
  99.  
  100.         targv[0] = line;
  101.         targc    = 1;
  102.     
  103.         /* pick up targv[0] */
  104.         while((*line != '\0') && (!isspace(*line)))
  105.             line++;
  106.  
  107.         if(*line != '\0')
  108.         {
  109.             *line++ = '\0';
  110.         }
  111.  
  112.         if((command = find_command(targv[0])) < 0)
  113.         {
  114.             fprintf(STDERR,"Invalid Command\n");
  115.             continue;
  116.         }
  117.  
  118.         if(expnd_args(line, comtab[command].expand))
  119.             /* too many args */
  120.             continue;
  121. #ifdef DEBUG
  122. printf("targc %d\n", targc);
  123. for(i = 0; i < targc; i++)
  124.     printf("%s ", targv[i]);
  125. printf("\n\n");
  126. #endif
  127.  
  128.         if((status = (*(comtab[command].routine))(targc, targv)) != 0)
  129.             fprintf(STDERR,"Exit Status %d\n", status);
  130.  
  131. #ifdef DEBUG
  132. printf("Exit Status %d\n", status);
  133. #endif
  134.  
  135.     } /* While */
  136. }
  137.  
  138. /*
  139.  * Straight sequential search thru comtab
  140.  */        
  141. int find_command(s)
  142. register char *s;
  143. {
  144.     register int i;
  145.  
  146.     for(i = 0; comtab[i].command != (char *)NULL; i++)
  147.     {
  148.         if(strcmp(s, comtab[i].command) == 0)
  149.             return i;
  150.     }
  151.  
  152.     return -1;
  153. }
  154.  
  155. /*
  156.  * Expand command line args, return TRUE if too many args, or Not matching Quotes
  157.  */
  158. int expnd_args(s, expand_wild)
  159. register char *s;
  160. int expand_wild;
  161. {
  162.     char next_arg[128];
  163.     register char *p;
  164.     register int contains_wild;
  165.     extern int add_argv();
  166.     extern int handl_wild();
  167.  
  168.     while(*s != '\0')
  169.     {
  170.         p = next_arg;
  171.         while(isspace(*s)) s++; /* skip leading space */
  172.         if(*s != '\0')
  173.         {
  174.             contains_wild = FALSE;
  175.             if(*s == '\047')
  176.             {
  177.                 /* Quoted arg */
  178.                 s++;
  179.                 while((*s != '\0') && (*s != '\047'))
  180.                     *p++ = *s++;
  181.                 *p = '\0';
  182.                 if(*s == '\0')
  183.                 {
  184.                     fprintf(STDERR,"No Matching Quote\n");
  185.                     return TRUE;
  186.                 }
  187.                 else
  188.                     s++;
  189.                 if(add_argv(next_arg))
  190.                     return TRUE;
  191.             }
  192.             else
  193.             {
  194.                 while(!isspace(*s) && (*s != '\0'))
  195.                 {
  196.                     contains_wild |= ISWILD(*s);
  197.                     *p++ = *s++;
  198.                 }
  199.                 *p = '\0';
  200.  
  201.                 if(contains_wild && expand_wild)
  202.                 {
  203.                     if(handl_wild(next_arg))
  204.                         return TRUE;
  205.                 }
  206.                 else
  207.                 {
  208.                     if(add_argv(next_arg))
  209.                         return TRUE;
  210.                 }
  211.             } /* if-else */
  212.         } /* If */
  213.     } /* while */
  214.  
  215.     return FALSE;
  216. }
  217.  
  218. /*
  219.  * add an arg to argv. Return TRUE if error
  220.  */
  221. int add_argv(s)
  222. char *s;
  223. {
  224.     extern char *strcpy();
  225. #ifdef __GNUC__
  226.     extern size_t strlen();
  227.     extern char *myalloc(unsigned int);
  228. #else
  229.     extern int strlen();
  230.     extern char *myalloc();
  231. #endif
  232.  
  233.     if(targc > (MAXARGS-1))
  234.     {
  235.         fprintf(STDERR,"Too many arguements (%d Max)\n", MAXARGS);
  236.         return TRUE;
  237.     }
  238.     targv[targc++] = strcpy(myalloc((unsigned int)(strlen(s)+1)), s);
  239.     
  240.     return FALSE;
  241.     
  242. }
  243.  
  244. /*
  245.  * expand wild card arguments. Return TRUE on error.
  246.  */
  247. int handl_wild(s)
  248. char *s;
  249. {
  250.     extern struct stat statbuf;
  251.     extern char *mkpathname();
  252.     
  253.     if(Fsfirst(s, 0x21) != 0)
  254.     {
  255.         /* No match */
  256.         fprintf(STDERR,"No Match for %s\n", s);
  257.         return TRUE;
  258.     }
  259.  
  260.     alltolower(statbuf.st_name);
  261.     if(add_argv(mkpathname(s, statbuf.st_name)))
  262.         return TRUE;
  263.  
  264.     while(Fsnext() == 0)
  265.     {
  266.         alltolower(statbuf.st_name);
  267.         if(add_argv(mkpathname(s, statbuf.st_name)))
  268.             return TRUE;
  269.     }
  270.  
  271.     return FALSE;
  272. }
  273.  
  274. /*
  275.  * Given a spec with a trailing wildcard and a base will name construct pathname
  276.  *
  277.  */
  278. char *mkpathname(spec, file)
  279. register char *spec, *file;
  280. {
  281.     extern char *rindex();
  282.     register char *p;
  283.  
  284.     if((p = rindex(spec, '\\')) == (char *)NULL)
  285.         /* no path name */
  286.         return file;
  287.  
  288.     while(*file != '\0')
  289.         *++p = *file++;
  290.     *++p = '\0';
  291.     
  292.     return spec;
  293. }
  294.  
  295. void free_args()
  296. {
  297.     register int i;
  298.     
  299.     for(i = 1; i < targc; i++)
  300.         free(targv[i]);
  301. }
  302.  
  303. /*
  304.  * remove files
  305.  *    Usage: rm [-i] files ... 
  306.  */    
  307. int rm(argc, argv)
  308. register int argc;
  309. register char **argv;
  310. {
  311.     register int interactive;
  312.     register int status;
  313.     extern int yesno();
  314.     extern int errno;
  315.  
  316.     interactive = FALSE;
  317.     status = 0;
  318.     while(--argc)
  319.     {
  320.         ++argv;
  321.         if( ((*argv)[0] == '-') && ((*argv)[1] == 'i') )
  322.             interactive = TRUE;
  323.         else
  324.         {
  325.             if(interactive)
  326.                 if(!yesno("rm: remove", *argv))
  327.                     continue;
  328.             if(unlink(*argv))
  329.             {
  330.                 status++;
  331.                 fprintf(STDERR, "%s: no such file\n", *argv);
  332.             }
  333.         }
  334.     }
  335.     return status;
  336. }
  337.  
  338. /*
  339.  * Prompt and return Yes/No truth value
  340.  *
  341.  */
  342. int yesno(p1, p2)
  343. register char *p1, *p2;
  344. {
  345.     char reply[16];
  346.  
  347.     fprintf(STDERR,"%s %s (y/n): ", p1, p2);
  348.     reply[0] = 16;
  349. #ifndef REMOTE
  350.     Cconrs(reply);
  351. #else
  352.     Cconraux(reply);
  353. #endif
  354.  
  355.     putc('\n', STDERR);
  356.     return ( (reply[2] == 'y') || (reply[2] == 'Y') );
  357.  
  358. }
  359.  
  360. /*
  361.  * copy files
  362.  *    Usage:
  363.  *        cp src dest
  364.  *        or
  365.  *        cp files.. directory
  366.  */
  367. int cp(argc, argv)
  368. int argc;
  369. char **argv;
  370. {
  371.     char dest[128];
  372.     register int status;
  373. #ifdef __GNUC__
  374.     extern size_t strlen();
  375. #else
  376.     extern int strlen();
  377. #endif
  378.     extern int cpy();
  379.     extern char *basename();
  380.     
  381.     status = 0;
  382.     if(argc > 3)
  383.     {
  384.         register int i;
  385.  
  386.         if(!existd(argv[argc-1]))
  387.         {
  388.             fprintf(STDERR,"%s does not exists or is not a directory\n",
  389.                 argv[argc-1]);
  390.             return 1;
  391.         }
  392.  
  393.         for(i = 1; i < argc - 1; i++)
  394.         {
  395.             strcpy(dest, argv[argc-1]);
  396.             if( (argv[argc-1])[((int)strlen(argv[argc-1])-1)] != '\\')
  397.                 strcat(dest, "\\");
  398.             strcat(dest, basename(argv[i]));
  399.  
  400.             fprintf(STDERR,"copying %s to %s\n", argv[i], dest);
  401.             status |= cpy(argv[i], dest);
  402.         }
  403.     }
  404.     else
  405.     {
  406.         if(argc > 2)
  407.         {
  408.             if(existd(argv[2]))
  409.             {
  410.                 /* dest is a directory */
  411.                 strcpy(dest, argv[2]);
  412.                 if( (argv[2])[((int)strlen(argv[2])-1)] != '\\')
  413.                     strcat(dest, "\\");
  414.  
  415.                 strcat(dest, basename(argv[1]));
  416.  
  417.                 fprintf(STDERR,"copying %s to %s\n", argv[1], dest);
  418.                 return (cpy(argv[1], dest));
  419.             }
  420.  
  421.             if(strcmp(argv[1], argv[2]) == 0)
  422.             {
  423.                 fprintf(STDERR,"Cannot copy a file onto itself\n");
  424.                 return 3;
  425.             }
  426.             status = cpy(argv[1], argv[2]);
  427.         }
  428.         else
  429.         {
  430.             fprintf(STDERR,"Usage: cp source dest or cp files .. directory\n");
  431.             return 2;
  432.         }
  433.     }
  434.  
  435.     return status;
  436. }
  437.  
  438.  
  439. /*
  440.  * Cpy src -> dest
  441.  *
  442.  */
  443. int cpy(src, dest)
  444. char *src, *dest;
  445. {
  446.     register int fps,fpd;
  447.     register long count;
  448.     register int status;
  449.  
  450.     status = 0;
  451.  
  452.     if((fps = Fopen(src, 0)) < (-3))
  453.     {
  454.         status = fps;
  455.         fprintf(STDERR,"%s: no s